package com.ddwl.message.service;

import com.ddwl.common.constant.BaseEnum;
import org.springframework.util.CollectionUtils;
import com.ddwl.common.constant.Constant;
import com.ddwl.common.constant.MessageReceiveTypeEnum;
import com.ddwl.common.exception.ParamException;
import com.ddwl.common.feign.api.ShopApi;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.MySqlUtil;
import com.ddwl.common.util.UUIDGenerator;
import com.ddwl.message.dao.ShopMessageInfoDao;
import com.ddwl.message.dao.ShopMessageUserDao;
import com.ddwl.message.model.ShopMessageInfo;
import com.ddwl.message.model.ShopMessageUser;
import com.ddwl.message.model.ShopMessageUserList;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.gate.ShopMessageInfoBo;
import com.ddwl.schema.bo.gate.ShopMessageInfoCreateBo;
import com.ddwl.schema.bo.gate.ShopMessageUserBo;
import com.ddwl.schema.bo.message.ShopMessageBo;
import com.ddwl.schema.bo.shop.QueryShopBo;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.base.RestVo;
import com.ddwl.schema.vo.gate.*;
import com.ddwl.schema.vo.shop.ShopVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wenbin
 */
@Service
public class ShopMessageNoticeService {

    @Autowired
    private ShopMessageInfoDao messageInfoDao;
    @Autowired
    private ShopMessageUserDao messageUserDao;
    @Resource
    private ShopApi shopApi;


    /**
     * 消息配置列表
     */
    public PageVo<ShopMessageInfoVo> getList(PageBo<ShopMessageInfoBo> bo) {
        PageHelper.startPage(bo.getPage(), bo.getPageSize(), MySqlUtil.orderBy(bo.getSort(), bo.isAsc()));
        List<ShopMessageInfo> infos = messageInfoDao.select(BeanConverUtils.convertBean(bo.getParam(), ShopMessageInfo.class));
        PageInfo<ShopMessageInfo> pageInfo = new PageInfo<>(infos);
        List<ShopMessageInfoVo> messageInfoVos = BeanConverUtils.convertBeanList(pageInfo.getList(), ShopMessageInfoVo.class);
        return new PageVo<>(pageInfo.getTotal(), bo.getPage(), bo.getPageSize(),messageInfoVos);
    }

    /**
     * 创建消息配置模板
     *
     * @param bo
     */
    @Transactional(rollbackFor = Exception.class)
    public void createMessage(ShopMessageInfoCreateBo bo){
        if(bo.getPushTime()==null){
            bo.setPushTime(Instant.now());
        }
        ShopMessageInfo messageInfo = BeanConverUtils.convertBean(bo, ShopMessageInfo.class);
        messageInfo.setId(UUIDGenerator.getShortUUID());
        messageInfoDao.insert(messageInfo);
        //所有门店
        if (MessageReceiveTypeEnum.ALL_SHOP.getCode().equals(bo.getType())) {
            ((ShopMessageNoticeService) AopContext.currentProxy()).sentMsg(messageInfo,null);
        }
        //指定门店
        if (MessageReceiveTypeEnum.SHOP.getCode().equals(bo.getType())) {
            ParamException.isTrue(CollectionUtils.isEmpty(bo.getShopList()),"指定商户列表未空");
            List<String> shopIds=bo.getShopList().stream().map(ShopMessageUserBo::getShopId).collect(Collectors.toList());
            ((ShopMessageNoticeService) AopContext.currentProxy()).sentMsg(messageInfo,shopIds);
        }
    }
    @Async
    public void sentMsg(ShopMessageInfo messageInfo,List<String> ids) {
        PageBo<QueryShopBo> pageBo = createShopPageBo(ids);
        RestVo<PageVo<ShopVo>> shopPageForApi = shopApi.getShopPageForApi(pageBo);
        PageVo<ShopVo> pageVo = shopPageForApi.getResult();
        Long total = pageVo.getTotal();
        insertShopMessageUser(messageInfo, pageVo.getData());
        int eachSize = pageBo.getPageSize();
        if (total > eachSize) {
            long totalPage = total % eachSize == 0 ? total / eachSize : (total / eachSize) + 1;
            for (int i = 0; i < totalPage-1; i++) {
                pageBo.setPage(i + 2);
                PageVo<ShopVo> userPage1 =shopApi.getShopPageForApi(pageBo).getResult();
                insertShopMessageUser(messageInfo, userPage1.getData());
            }
        }
    }

    public void insertShopMessageUser(ShopMessageInfo messageInfo, List<ShopVo> shopVoList) {
        List<ShopMessageUser> messageUsers = new ArrayList<>();
        for (ShopVo shopVo : shopVoList) {
            ShopMessageUser messageUser=new ShopMessageUser();
            messageUser.setId(UUIDGenerator.getShortUUID());
            messageUser.setUserId(shopVo.getUserId());
            messageUser.setShopId(shopVo.getId());
            messageUser.setUserPhone(shopVo.getUserTel());
            messageUser.setMessageInfoId(messageInfo.getId());
            messageUser.setReadStatus(BaseEnum.ReadEnum.UNREAD.getCode());
            messageUser.setDflag(0);
            messageUser.setGmtCreated(Instant.now());
            messageUser.setGmtModified(Instant.now());
            messageUsers.add(messageUser);
        }
        messageUserDao.insertByList(messageUsers);
    }

    private PageBo<QueryShopBo> createShopPageBo(List<String> ids) {
        PageBo<QueryShopBo> pageBo = new PageBo<>();
        pageBo.setPageSize(100);
        pageBo.setAsc(true);
        pageBo.setSort("gmtCreated");

        QueryShopBo queryShopBo=new QueryShopBo();
        queryShopBo.setSystemStop(0);
        if (!CollectionUtils.isEmpty(ids)) {
            queryShopBo.setIdList(ids);
        }
        pageBo.setParam(queryShopBo);
        return pageBo;
    }

    public ShopMessageInfoVo detail(String id){
        ShopMessageInfoVo messageInfoVo=BeanConverUtils.convertBean(messageInfoDao.selectByPrimaryKey(id),ShopMessageInfoVo.class);
        return messageInfoVo;
    }

    public void delete(String messagInfoId){
        messageInfoDao.deleteById(messagInfoId);
        messageUserDao.deleteByMessageId(messagInfoId);
    }

    /**
     * 查询当前用户下的消息列表
     */
    public PageVo<ShopMessageUserListVo> messageList(PageBo<ShopMessageUserBo> bo){
        ParamException.isBlank(bo.getParam().getShopId(),"门店id为空");
        PageHelper.startPage(bo.getPage(),bo.getPageSize(),MySqlUtil.orderBy(bo.getSort(),bo.isAsc()));
        List<ShopMessageUserList> listByUserId = messageUserDao.getListByShopId(bo.getParam().getShopId());
        PageInfo<ShopMessageUserList> info=new PageInfo<>(listByUserId);
        List<ShopMessageUserListVo> messageUserListVos = BeanConverUtils.convertBeanList(info.getList(), ShopMessageUserListVo.class);
        return new PageVo<>(info.getTotal(),bo.getPage(),bo.getPageSize(),messageUserListVos);
    }

    /**
     * 查看消息详情，更改消息状态为已读
     * @param messageUserBo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ShopMessageInfoDetailVo getMessageDetail(ShopMessageUserBo messageUserBo){
        ParamException.isBlank(messageUserBo.getShopId(),"门店id为空");
        messageUserDao.updateReadStatus(messageUserBo.getShopId(),messageUserBo.getMessageInfoId());
        return BeanConverUtils.convertBean(messageInfoDao.selectByPrimaryKey(messageUserBo.getMessageInfoId()),ShopMessageInfoDetailVo.class);
    }

    /**
     * 获取该消息下的数据列表
     */
    public PageVo<ShopMessageDataVo> getDataList(PageBo<ShopMessageUserBo> bo){
        PageHelper.startPage(bo.getPage(),bo.getPageSize(),MySqlUtil.orderBy(bo.getSort(),bo.isAsc()));
        PageInfo<ShopMessageUser> messageDataVoPageInfo = new PageInfo<>(messageUserDao.getList(BeanConverUtils.convertBean(bo.getParam(),ShopMessageUser.class)));
        List<ShopMessageDataVo> list = BeanConverUtils.convertBeanList(messageDataVoPageInfo.getList(), ShopMessageDataVo.class);
        return new PageVo<>(messageDataVoPageInfo.getTotal(),bo.getPage(),bo.getPageSize(),list);
    }


    /**
     * 判断该用户是否有未读消息
     */
    public ShopMessageIsReadVo hasUnRead(String shopId){
        ParamException.isBlank(shopId,"门店id为空");
        ShopMessageUser messageUser=new ShopMessageUser();
        ShopMessageIsReadVo messageIsReadVo=new ShopMessageIsReadVo();
        messageUser.setShopId(shopId);
        messageUser.setReadStatus(BaseEnum.ReadEnum.UNREAD.getCode());
        if(!messageUserDao.getHasRead(messageUser).isEmpty()){
            messageIsReadVo.setHasReaded(BaseEnum.ReadEnum.READED.getCode());
        }
        return messageIsReadVo;
    }

    public void pushMessageToShop(ShopMessageBo bo) {
        ShopMessageInfo messageInfo = BeanConverUtils.convertBean(bo, ShopMessageInfo.class);
        messageInfoDao.insert(messageInfo);
        RestVo<ShopVo> restVo = shopApi.getShopById(bo.getShopId());
        ShopVo shopVo = restVo.getResult();
        ShopMessageUser messageUser=new ShopMessageUser();
        if (null != shopVo) {
            messageUser.setUserId(shopVo.getUserId());
            messageUser.setUserPhone(shopVo.getUserTel());
        }
        messageUser.setShopId(bo.getShopId());
        messageUser.setMessageInfoId(messageInfo.getId());
        messageUser.setReadStatus(BaseEnum.ReadEnum.UNREAD.getCode());
        messageUserDao.insert(messageUser);
    }

    public void changeId() {
        List<ShopMessageInfo> list=messageInfoDao.getAll();
        if (!CollectionUtils.isEmpty(list)) {
            Map<String, String> map = new HashMap<>();
            for (ShopMessageInfo messageInfo : list) {
                String id = messageInfo.getId();
                if (id.length() == 11) {
                    long longId = UUIDGenerator.reverseShortUUID(id);
                    map.put(id, String.valueOf(longId));
                }
            }
            if (!CollectionUtils.isEmpty(map)) {
                messageInfoDao.changeId(map);
                messageUserDao.changeMessageInfoId(map);
            }
        }
        List<ShopMessageUser> messageUsers=messageUserDao.getAll();
        if (!CollectionUtils.isEmpty(messageUsers)) {
            Map<String, String> map = new HashMap<>();
            for (ShopMessageUser smu : messageUsers) {
                String id = smu.getId();
                if (id.length() == 11) {
                    long longId = UUIDGenerator.reverseShortUUID(id);
                    map.put(id, String.valueOf(longId));
                }
            }
            if (!CollectionUtils.isEmpty(map)) {
                messageUserDao.changeId(map);
            }
        }
    }
}
